import { reactive } from 'vue'
import type { InjectionKey } from 'vue'
import app from '@/app'

export const modulePlugins = reactive({})

export class NaiveAdmin {
  config?: System.AppConfig
  app: System.App = app
  constructor(config?: System.AppConfig, callback?: System.AppCallback) {
    this.app = app
    this.config = config
    this.provide('appConfig', config)
    callback && callback(this)
  }

  public isProvide(key: any) {
    return Boolean(this.app._context.provides[key])
  }

  public isComponent(name: string) {
    return Boolean(this.app._context.components[name])
  }

  public getComponents() {
    return this.app._context.components
  }

  // @ts-ignore
  public provide<T, K = InjectionKey<T> | string | number>(key: K, value: K extends InjectionKey<infer V> ? V : T) {
    if (!this.isProvide(key as K)) {
      this.app.provide(key, value)
    }
    return this
  }

  public component<T extends System.VueComponent>(name: string, component?: T) {
    if (!this.isComponent(name)) {
      if (component) {
        this.app.component(name, component)
      } else {
        this.app.component(name)
      }
    }
    return this
  }

  public render(dom: string = '#app') {
    this.app.mount(dom)
  }
}

export declare type Type = typeof NaiveAdmin
